package com.example.onlinemusic.controller;

import com.example.onlinemusic.mapper.LoveMusicMapper;
import com.example.onlinemusic.mapper.MusicMapper;
import com.example.onlinemusic.model.Music;
import com.example.onlinemusic.model.User;
import com.example.onlinemusic.tools.Constant;
import com.example.onlinemusic.tools.ResponseBodyMessage;
import org.apache.ibatis.binding.BindingException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RequestPart;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;

@RestController
@RequestMapping("/music")
public class MusicController {
    @Value("${music.local.path}")//获取配置文件的值(此指的是上传到的目标路径)
    //private String SAVE_PATH/*="C:/work/local/music1/"*/;
    private String SAVE_PATH;
    @Autowired
    private MusicMapper musicMapper;

    @Resource
    private LoveMusicMapper loveMusicMapper;
                                                  //MultipartFile是spring框架中处理文件上传的主要类
    @RequestMapping("/upload")                        //filename对应upload.html中form表单的filename
    public ResponseBodyMessage<Boolean> insertMusic(@RequestParam String singer,
                                                    @RequestPart("filename") MultipartFile file,
                                                    HttpServletRequest request,
                                                     HttpServletResponse response){
             //1.检测是否登录了                     //@RequestParam告诉这个参数是从请求参数中获取的,一旦没有就报错
        HttpSession httpSession= request.getSession(false);
        //getAttribute括号里的内容代表k值.代表要要获取的value(此指user对象)
        if(httpSession==null||httpSession.getAttribute(Constant.USERINFO_SESSION_KEY)==null){
            System.out.println("没有登录! ");
            return new ResponseBodyMessage<>(-1,"请登录后上传",false);
        }

        //2. 查询当前数据库是否有当前音乐
        //判断依据(歌曲名+歌手)一样就不能上传

        //3. 上传到服务器
        //fileNameAndType代表文件的完整名称(文件名+类型)
        String fileNameAndType=file.getOriginalFilename();//文件的完整类型(xxx.png)
        System.out.println("fileNameAndType: "+fileNameAndType);
            String path=SAVE_PATH+"\\"+fileNameAndType;
            File dest=new File(path);
            //该路径下的文件是否存在,不存在就创建目标目录
            if(!dest.exists()){
                dest.mkdirs();
            }
        try {
            file.transferTo(dest);//上传目标文件
            //return new ResponseBodyMessage<>(0,"上传成功",true);
        } catch (IOException e) {
            e.printStackTrace();
            //return new ResponseBodyMessage<>(-1,"服务器上传失败",false);
        }
        //这里对是否为mp3文件进行判定,主要判断是否存在TAG这个字符
        byte[]res=null;
        try {
            res=Files.readAllBytes(dest.toPath());
            //readAllBytes读取文件中的所有字节。 该方法确保在读取所有字节或抛出I / O错误或其他运行时异常时关闭文件。
            //请注意，此方法适用于将所有字节读入字节数组的简单情况。 它不是用于阅读大文件。
            if(res==null){
                return new ResponseBodyMessage<>(-1,"当前文件不存在",false);
            }
            String str=new String(res);
            if(!str.contains("TAG")){
                dest.delete();
                return new ResponseBodyMessage<>(-1,"当前文件不是mp3文件",false);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }

        //进行数据库的上传
        //1.准备数据 2.调用insert
        //lastIndexOf从后往前遍历
        int index=fileNameAndType.lastIndexOf(".");
        String title=fileNameAndType.substring(0,index);
        //获取登录用户id
        User user=(User)httpSession.getAttribute(Constant.USERINFO_SESSION_KEY);
        int userid=user.getId();

        //url的作用:1.播放音乐(http请求) 2.存进去的时候没有加后缀名(.mp3)
        String url="/music/get?path="+title;

        SimpleDateFormat sf=new SimpleDateFormat("yyyy-MM-dd");
        //sf.format(new Date())把当前时间格式成字符串
        String time=sf.format(new Date());
        try {
            int ret=0;
            ret=musicMapper.insert(title,singer,time,url,userid);
            if(ret==1){
                //这里应该跳转到音乐列表的页面
                response.sendRedirect("/list.html");
                return new ResponseBodyMessage<>(0,"数据库上传成功",true);
            }else{
                return new ResponseBodyMessage<>(-1,"数据库上传失败",false);
            }
        }catch (BindingException | IOException e){
            dest.delete();
            return new ResponseBodyMessage<>(-1,"数据库上传失败",false);
        }
    }

    //播放音乐的时候路径为: /music/get?path=xxx.mp3
    @RequestMapping("/get")
    //返回的数据是响应体中的内容
    //这个方法判断是否是mp3文件(是否包含TAG标签)
    public ResponseEntity<byte[]>get(String path){
        File file=new  File(SAVE_PATH+"/"+path);
        byte[]a= null;
        try {
            //readAllBytes方法是读取文件中的所有字节,参数是文件的路径
            //该方法是把路径下的文件转化为字节流放到byte数组里
            a = Files.readAllBytes(file.toPath());
            if(a==null){
                //返回400错误
                //ResponseEntity对象是Spring对请求响应的封装。它继承了HttpEntity对象，包含了Http的响应码
                //（httpstatus）、响应头（header）、响应体(body)三个部分。
                return ResponseEntity.badRequest().build();
            }
            return ResponseEntity.ok(a);
        } catch (IOException e) {
            e.printStackTrace();
            return ResponseEntity.badRequest().build();
        }
        //返回500错误
        //return ResponseEntity.internalServerError().build();
        //返回404错误
        //return ResponseEntity.notFound().build();

        //(带有参数)ok方法返回的是响应体中的内容和状态码200
        //无参方法返回只返回状态码200
    }

    //删除单个音乐,返回状态信息(ResponseBodyMessage类下的)
    @RequestMapping("/delete")
    public ResponseBodyMessage<Boolean>deleteMusicById(@RequestParam String id){
        //1. 先检查音乐是否存在
        int iid=Integer.parseInt(id);
        //2. 如果存在要进行删除
        Music music=musicMapper.finMusicById(iid);
        if(music==null){
            System.out.println("没有这个id的音乐");
            return new ResponseBodyMessage<>(-1,"没有你要删除的音乐!",false);
        }else{
            //2.1 删除数据库中目标音乐
            int ret=musicMapper.deleteMusicById(iid);
            if(ret==1){
                //2.2 删除服务器上的数据
                int index=music.getUrl().lastIndexOf("=");
               String fileName= music.getUrl().substring(index+1);//音乐名称
                File file=new File(SAVE_PATH+"/"+fileName+".mp3");
                System.out.println("当前的路径: "+file.getPath());
                if (file.delete()){
                    //同步删除lovemusic表当中的这个音乐
                    loveMusicMapper.deleteLoveMusicById(iid);
                    return new ResponseBodyMessage<>(0,"服务器当中的音乐删除成功",true);
                }else{
                    return new ResponseBodyMessage<>(-1,"服务器当中的音乐删除失败",false);
                }
            }else {
                return new ResponseBodyMessage<>(-1,"数据库当中的音乐没有删除成功!",false);
            }
        }
    }

    //批量删除音乐
    @RequestMapping("/deleteSel")
    public ResponseBodyMessage<Boolean>deleteSelMusic(@RequestParam("id[]") List<Integer> id){
        System.out.println("所有的id: "+id);
        int sum=0;//用来记录删除的音乐
        for (int i = 0; i <id.size() ; i++) {
            int musicId=id.get(i);
            Music music=musicMapper.finMusicById(musicId);
            if(music==null){
                System.out.println("没有这个id的音乐");
                return new ResponseBodyMessage<>(-1,"没有你要删除的音乐!",false);
            }
            int ret=musicMapper.deleteMusicById(musicId);
            if(ret==1){
                int index=music.getUrl().lastIndexOf("=");
                String fileName= music.getUrl().substring(index+1);//音乐名称
                File file=new File(SAVE_PATH+"/"+fileName+".mp3");
                if(file.delete()){
                    //同步删除lovemusic表当中的这个音乐
                    loveMusicMapper.deleteLoveMusicById(musicId);
                    sum+=ret;
                }else{
                    return new ResponseBodyMessage<>(-1,"服务器中的音乐删除失败!",false);
                }
            }else{
                return new ResponseBodyMessage<>(-1,"数据库中的音乐删除失败!",false);
            }
        }
        if(sum==id.size()){
            System.out.println("整体删除成功!");
            return new ResponseBodyMessage<>(0,"音乐批量删除成功!",true);
        }else{
            System.out.println("整体删除失败");
            return new ResponseBodyMessage<>(-1,"音乐批量删除失败!",false);
        }
    }

    @RequestMapping("/findmusic")
    //required = false表示可以传空值
    //什么都不输入查询,查询的是所有音乐.
    public ResponseBodyMessage<List<Music>>findMusic(@RequestParam(required = false) String musicName){
        List<Music>musicList=null;
        if(musicName!=null){
          musicList= musicMapper.findMusicByName(musicName);
        }else{
            musicList=musicMapper.findMusic();
        }
        return new ResponseBodyMessage<>(0,"查询到了音乐",musicList);
    }
}
